home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / dev / src / stefanb_src.lha / Old_Projects / ToolManager / Source / library / handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-09  |  15.0 KB  |  552 lines

  1. /*
  2.  * handler.c  V2.1.07
  3.  *
  4.  * handler main loop
  5.  *
  6.  * (c) 1990-1996 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerLib.h"
  10.  
  11. /* Constant strings */
  12. static const char WBName[] = "Workbench";
  13.  
  14. /* misc. data */
  15. struct Library *DOSBase=NULL;
  16. struct Library *CxBase=NULL;
  17. struct Library *UtilityBase=NULL;
  18. struct IntuitionBase *IntuitionBase=NULL;
  19. struct Library *GfxBase=NULL;
  20. struct Library *GadToolsBase=NULL;
  21. struct Library *NIPCBase=NULL;
  22. struct Library *ScreenNotifyBase=NULL;
  23. extern const char DosName[];
  24. extern struct Library *LibBase;
  25. static struct NotifyRequest PrefsNotify={
  26.                                          PrefsFileName,NULL,0,
  27.                                          NRF_SEND_SIGNAL,NULL
  28.                                         };
  29. static ULONG EntitySignal=-1;
  30. static ULONG NotifySignal=-1;
  31. static UBYTE *HostNameBuffer=NULL;
  32. #define HOSTNAMEBUFLEN 256
  33. static APTR ScreenNotifyHandle1=NULL;
  34. static APTR ScreenNotifyHandle2=NULL;
  35. static APTR ScreenNotifyHandle3=NULL;
  36. static BOOL TimerOpen=FALSE;
  37. static BOOL NotifyActive=FALSE;
  38.  
  39. /* Open handler resources */
  40. static BOOL OpenResources(void)
  41. {
  42.  if (!(LibraryPort=CreateMsgPort()))                       return(FALSE);
  43.  if (!(DOSBase=OpenLibrary(DosName,39)))                   return(FALSE);
  44.  if (!(CxBase=OpenLibrary("commodities.library",39)))      return(FALSE);
  45.  if (!(UtilityBase=OpenLibrary("utility.library",39)))     return(FALSE);
  46.  if (!(IntuitionBase=(struct IntuitionBase *)
  47.                       OpenLibrary("intuition.library",39))) return(FALSE);
  48.  if (!(GfxBase=OpenLibrary("graphics.library",39)))        return(FALSE);
  49.  if (!(GadToolsBase=OpenLibrary("gadtools.library",39)))   return(FALSE);
  50.  if (!(DummyPort=CreateMsgPort()))                         return(FALSE);
  51.  if (!(IDCMPPort=CreateMsgPort()))                         return(FALSE);
  52.  if (!(TimerPort=CreateMsgPort()))                         return(FALSE);
  53.  if (!(AppMsgPort=CreateMsgPort()))                        return(FALSE);
  54.  if (!(BrokerPort=CreateMsgPort()))                        return(FALSE);
  55.  if (!(deftimereq=CreateIORequest(TimerPort,sizeof(struct timerequest))))
  56.                                                            return(FALSE);
  57.  if (OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *) deftimereq,
  58.                 0))                                        return(FALSE);
  59.  TimerOpen=TRUE;
  60.  if (!(PrivateTMHandle=AllocMem(sizeof(struct TMHandle),MEMF_PUBLIC)))
  61.                                                            return(FALSE);
  62.  if (!(InternalAllocTMHandle(PrivateTMHandle)))            return(FALSE);
  63.  if ((NotifySignal=AllocSignal(-1))==-1)                   return(FALSE);
  64.  PrefsNotify.nr_stuff.nr_Signal.nr_Task=FindTask(NULL);
  65.  PrefsNotify.nr_stuff.nr_Signal.nr_SignalNum=NotifySignal;
  66.  if (!StartNotify(&PrefsNotify))                           return(FALSE);
  67.  NotifyActive=TRUE;
  68.  BrokerData.nb_Port=BrokerPort;
  69.  
  70.  /* Get locale stuff */
  71.  GetLocale();
  72.  
  73.  if (!(Broker=CxBroker(&BrokerData,NULL)))                 return(FALSE);
  74.  
  75.  /* Copy path from Workbench process */
  76.  {
  77.   struct Process *wbproc=(struct Process *) FindTask(WBName);
  78.  
  79.   /* Task found? Make sure it IS a process */
  80.   if (wbproc && (wbproc->pr_Task.tc_Node.ln_Type==NT_PROCESS)) {
  81.    /* It is a process */
  82.    struct CommandLineInterface *wbcli=BADDR(wbproc->pr_CLI);
  83.  
  84.    /* Make sure it is a CLI process */
  85.    if (wbcli) {
  86.     /* It is a CLI process */
  87.     struct PathList *dummy;
  88.  
  89.     /* Copy it's path into global path */
  90.     if (!CopyPathList(&GlobalPath,&dummy,
  91.                       (struct PathList *) BADDR(wbcli->cli_CommandDir)))
  92.      return(FALSE);
  93.    }
  94.   }
  95.  }
  96.  
  97.  /* Get ScreenNotify stuff */
  98.  if (ScreenNotifyBase = OpenLibrary("screennotify.library", 0)) {
  99.  
  100.   /* Allocate message port */
  101.   if (!(ScreenNotifyPort = CreateMsgPort())) return(FALSE);
  102.  
  103.   /* Add handler as client */
  104.   ScreenNotifyHandle1 = AddCloseScreenClient(NULL, ScreenNotifyPort, 0);
  105.   ScreenNotifyHandle2 = AddPubScreenClient(ScreenNotifyPort, 0);
  106.   ScreenNotifyHandle3 = AddWorkbenchClient(ScreenNotifyPort, 0);
  107.  }
  108.  
  109.  /* Get network stuff */
  110.  if (NIPCBase=OpenLibrary("nipc.library",37)) {
  111.   /* Create local public entity */
  112.   if (!(LocalEntity=CreateEntity(ENT_AllocSignal, &EntitySignal,
  113.                                  ENT_Name,        ToolManagerName,
  114.                                  ENT_Public,      TRUE,
  115.                                  TAG_DONE)))
  116.    return(FALSE);
  117.  
  118.   if (!(HostNameBuffer=AllocMem(HOSTNAMEBUFLEN,MEMF_PUBLIC))) return(FALSE);
  119.  }
  120.  
  121.  /* All OK. */
  122.  return(TRUE);
  123. }
  124.  
  125. /* Free handler resources */
  126. static void FreeResources(void)
  127. {
  128.  if (HostNameBuffer) {
  129.   FreeMem(HostNameBuffer,HOSTNAMEBUFLEN);
  130.   HostNameBuffer=NULL;
  131.  }
  132.  if (LocalEntity) {
  133.   DeleteEntity(LocalEntity);
  134.   LocalEntity=NULL;
  135.   EntitySignal=-1;
  136.  }
  137.  if (NIPCBase) {
  138.   CloseLibrary(NIPCBase);
  139.   NIPCBase=NULL;
  140.  }
  141.  
  142.  if (ScreenNotifyHandle3) {
  143.   while (!RemWorkbenchClient(ScreenNotifyHandle3)) Delay(10);
  144.   ScreenNotifyHandle3 = NULL;
  145.  }
  146.  if (ScreenNotifyHandle2) {
  147.   while (!RemPubScreenClient(ScreenNotifyHandle2)) Delay(10);
  148.   ScreenNotifyHandle2 = NULL;
  149.  }
  150.  if (ScreenNotifyHandle1) {
  151.   while (!RemCloseScreenClient(ScreenNotifyHandle1)) Delay(10);
  152.   ScreenNotifyHandle1 = NULL;
  153.  }
  154.  if (ScreenNotifyPort) {
  155.   DeleteMsgPort(ScreenNotifyPort);
  156.   ScreenNotifyPort = NULL;
  157.  }
  158.  if (ScreenNotifyBase) {
  159.   CloseLibrary(ScreenNotifyBase);
  160.   ScreenNotifyBase = NULL;
  161.  }
  162.  
  163.  FreePathList(GlobalPath); /* FreePath checks for NULL */
  164.  GlobalPath=NULL;
  165.  
  166.  if (Broker) {
  167.   DeleteCxObjAll(Broker);
  168.   Broker=NULL;
  169.  }
  170.  FreeLocale();
  171.  if (NotifyActive) {
  172.   EndNotify(&PrefsNotify);
  173.   NotifyActive=FALSE;
  174.  }
  175.  if (NotifySignal != -1) {
  176.   FreeSignal(NotifySignal);
  177.   NotifySignal=-1;
  178.  }
  179.  if (PrivateTMHandle) {
  180.   InternalFreeTMHandle(PrivateTMHandle);
  181.   FreeMem(PrivateTMHandle,sizeof(struct TMHandle));
  182.   PrivateTMHandle=NULL;
  183.  }
  184.  if (TimerOpen) {
  185.   CloseDevice((struct IORequest *) deftimereq);
  186.   TimerOpen=FALSE;
  187.  }
  188.  if (deftimereq) {
  189.   DeleteIORequest(deftimereq);
  190.   deftimereq=NULL;
  191.  }
  192.  if (BrokerPort) {
  193.   struct Message *msg;
  194.   while (msg=GetMsg(BrokerPort)) ReplyMsg(msg);
  195.   DeleteMsgPort(BrokerPort);
  196.   BrokerPort=NULL;
  197.  }
  198.  if (AppMsgPort) {
  199.   struct Message *msg;
  200.   while (msg=GetMsg(AppMsgPort)) ReplyMsg(msg);
  201.   DeleteMsgPort(AppMsgPort);
  202.   AppMsgPort=NULL;
  203.  }
  204.  if (TimerPort) {
  205.   DeleteMsgPort(TimerPort);
  206.   TimerPort=NULL;
  207.  }
  208.  if (IDCMPPort) {
  209.   DeleteMsgPort(IDCMPPort);
  210.   IDCMPPort=NULL;
  211.  }
  212.  if (DummyPort) {
  213.   DeleteMsgPort(DummyPort);
  214.   DummyPort=NULL;
  215.  }
  216.  if (GadToolsBase) {
  217.   CloseLibrary(GadToolsBase);
  218.   GadToolsBase=NULL;
  219.  }
  220.  if (GfxBase) {
  221.   CloseLibrary(GfxBase);
  222.   GfxBase=NULL;
  223.  }
  224.  if (IntuitionBase) {
  225.   CloseLibrary((struct Library *) IntuitionBase);
  226.   IntuitionBase=NULL;
  227.  }
  228.  if (UtilityBase) {
  229.   CloseLibrary(UtilityBase);
  230.   UtilityBase=NULL;
  231.  }
  232.  if (CxBase) {
  233.   CloseLibrary(CxBase);
  234.   CxBase=NULL;
  235.  }
  236.  if (DOSBase) {
  237.   CloseLibrary(DOSBase);
  238.   DOSBase=NULL;
  239.  }
  240.  if (LibraryPort) {
  241.   DeleteMsgPort(LibraryPort);
  242.   LibraryPort=NULL;
  243.  }
  244. }
  245.  
  246. /* Screen open event */
  247. static void ScreenOpenEvent(char *name)
  248. {
  249.  struct TMObject *tmobj = GetHead(&PrivateTMHandle->tmh_ObjectLists[TMOBJTYPE_DOCK]);
  250.  
  251.  /* Traverse list */
  252.  while (tmobj) {
  253.   /* Open dock */
  254.   ScreenOpenRequest(tmobj, name);
  255.  
  256.   /* Get next object */
  257.   tmobj = GetSucc(tmobj);
  258.  }
  259. }
  260.  
  261. /* Screen close event */
  262. static void ScreenCloseEvent(struct Screen *s)
  263. {
  264.  struct TMObject *tmobj = GetHead(&PrivateTMHandle->tmh_ObjectLists[TMOBJTYPE_DOCK]);
  265.  
  266.  /* Traverse list */
  267.  while (tmobj) {
  268.   /* Close dock */
  269.   ScreenCloseRequest(tmobj, s);
  270.  
  271.   /* Get next object */
  272.   tmobj = GetSucc(tmobj);
  273.  }
  274. }
  275.  
  276. /* handler main entry point */
  277. __geta4 void HandlerEntry(void)
  278. {
  279.  ULONG sigmask,lpsig,ipsig,tpsig,apsig,bpsig,nwsig,npsig,scsig;
  280.  
  281.  /* Get resources */
  282.  if (!OpenResources()) {
  283.   FreeResources();
  284.   return;
  285.  }
  286.  
  287.  /* Read config */
  288.  if (!Closing) ReadConfig();
  289.  
  290.  /* Build signal masks */
  291.  lpsig = 1L << LibraryPort->mp_SigBit;
  292.  ipsig = 1L << IDCMPPort->mp_SigBit;
  293.  tpsig = 1L << TimerPort->mp_SigBit;
  294.  apsig = 1L << AppMsgPort->mp_SigBit;
  295.  bpsig = 1L << BrokerPort->mp_SigBit;
  296.  nwsig = (EntitySignal != -1) ? (1L << EntitySignal) : 0;
  297.  npsig = 1L << NotifySignal;
  298.  scsig = (ScreenNotifyPort != NULL) ? (1L << ScreenNotifyPort->mp_SigBit) : 0;
  299.  
  300.  sigmask=ipsig|lpsig|tpsig|apsig|bpsig|nwsig|npsig|scsig|SIGBREAKF_CTRL_F;
  301.  
  302.  /* Activate broker */
  303.  ActivateCxObj(Broker,TRUE);
  304.  
  305.  /* Wait until the end...*/
  306.  while (!Closing || (LibBase->lib_OpenCnt>0)) {
  307.   ULONG gotsigs;
  308.  
  309.   /* Wait for events */
  310.   DEBUG_PUTSTR("Handler: Waiting for messages...\n")
  311.   gotsigs=Wait(sigmask);
  312.  
  313.   /* Got an IDCMP event? (only dock objects!) */
  314.   if (gotsigs & ipsig) HandleIDCMPEvents();
  315.  
  316.   /* Got a timer event? */
  317.   if (gotsigs & tpsig) {
  318.    struct List *l=&TimerPort->mp_MsgList;
  319.    struct TMTimerReq *tr;
  320.  
  321.    /* Scan message list (special treatment for I/O Requests!) */
  322.    while (tr=GetHead(l)) CallActivateTMObject(tr->tmtr_Link,NULL);
  323.   }
  324.  
  325.   /* Got a Workbench App* message? */
  326.   if (gotsigs & apsig) {
  327.    struct AppMessage *msg;
  328.  
  329.    /* Empty message queue */
  330.    while (msg=(struct AppMessage *) GetMsg(AppMsgPort)) {
  331.     /* Activate object */
  332.     CallActivateTMObject((struct TMLink *) msg->am_ID,msg);
  333.  
  334.     /* Reply message */
  335.     ReplyMsg((struct Message *) msg);
  336.    }
  337.   }
  338.  
  339.   /* Got a Commodities event? */
  340.   if (gotsigs & bpsig) {
  341.    CxMsg *msg;
  342.  
  343.    /* Empty message queue */
  344.    while (msg=(CxMsg *) GetMsg(BrokerPort)) {
  345.  
  346.     DEBUG_PRINTF("Commodities event (0x%08lx)\n",CxMsgType(msg));
  347.  
  348.     /* What type of Commodities event? */
  349.     switch (CxMsgType(msg)) {
  350.      case CXM_IEVENT: /* Hotkey event --> Activate object */
  351.                      CallActivateTMObject((struct TMLink *) CxMsgID(msg),
  352.                                           NULL);
  353.                      break;
  354.  
  355.      case CXM_COMMAND: /* Commodities command */
  356.                       switch (CxMsgID(msg)) {
  357.                        case CXCMD_DISABLE: /* Disable broker */
  358.                                           ActivateCxObj(Broker,FALSE);
  359.                                           break;
  360.  
  361.                        case CXCMD_ENABLE:  /* Enable broker */
  362.                                           ActivateCxObj(Broker,TRUE);
  363.                                           break;
  364.  
  365.                        case CXCMD_KILL:    /* Quit application */
  366.                                           Closing=TRUE;
  367.                                           break;
  368.                        }
  369.                       break;
  370.     }
  371.  
  372.     /* Reply message */
  373.     ReplyMsg((struct Message *) msg);
  374.    }
  375.   }
  376.  
  377.   /* Got a network event? */
  378.   if (gotsigs & nwsig) {
  379.    struct Transaction *trans;
  380.  
  381.    /* Empty transaction queue */
  382.    while (trans=GetTransaction(LocalEntity)) {
  383.     struct TMLink *tml=NULL;
  384.     ULONG errcode=ENVOYERR_APP;
  385.  
  386.     /* Get host name of remote machine */
  387.     if (GetHostName(trans->trans_SourceEntity,HostNameBuffer,HOSTNAMEBUFLEN))
  388.  
  389.      /* Search Access object (with full host name) */
  390.      if (!(tml=AddLinkTMObject(PrivateTMHandle,HostNameBuffer,TMOBJTYPE_ACCESS,
  391.                                NULL))) {
  392.       char *realm;
  393.  
  394.       /* Locate realm part */
  395.       if (realm=strchr(HostNameBuffer,':')) {
  396.        /* Set string terminator */
  397.        *realm='\0';
  398.  
  399.        /* Search Access object (with realm name) */
  400.        tml=AddLinkTMObject(PrivateTMHandle,HostNameBuffer,TMOBJTYPE_ACCESS,
  401.                                NULL);
  402.       }
  403.      }
  404.  
  405.     DEBUG_PRINTF("Host name: '%s'\n",HostNameBuffer);
  406.  
  407.     /* Object not found? */
  408.     if (!tml)
  409.      /* Search default Access object */
  410.      tml=AddLinkTMObject(PrivateTMHandle,"anyone",TMOBJTYPE_ACCESS,NULL);
  411.  
  412.     DEBUG_PRINTF("Link: 0x%08lx\n",tml);
  413.  
  414.     /* Object found? */
  415.     if (tml) {
  416.      /* Yes, activate Access object */
  417.      CallActivateTMObject(tml,trans->trans_RequestData);
  418.  
  419.      /* Remove link */
  420.      RemLinkTMObject(tml);
  421.  
  422.      /* All OK (hope so :-) */
  423.      errcode=ENVOYERR_NOERROR;
  424.     }
  425.  
  426.     /* Reply transaction */
  427.     trans->trans_Error=errcode;
  428.     ReplyTransaction(trans);
  429.    }
  430.   }
  431.  
  432.   /* Got a command from the library interface? */
  433.   if (gotsigs & lpsig) {
  434.    struct TMHandle *handle;
  435.  
  436.    /* Empty message queue */
  437.    while (handle=(struct TMHandle *) GetMsg(LibraryPort)) {
  438.     BOOL rc=FALSE;
  439.  
  440.     DEBUG_PRINTF("Got command (%1lx)\n",handle->tmh_Command);
  441.  
  442.     /* What command did we receive? */
  443.     switch (handle->tmh_Command) {
  444.      case TMIPC_AllocTMHandle:  rc=InternalAllocTMHandle(handle);
  445.                                 break;
  446.  
  447.      case TMIPC_FreeTMHandle:   rc=InternalFreeTMHandle(handle);
  448.                                 break;
  449.  
  450.      case TMIPC_CreateTMObject: rc=InternalCreateTMObject(handle,
  451.                                                           handle->tmh_Object,
  452.                                                           handle->tmh_Type,
  453.                                                           handle->tmh_Tags);
  454.                                 break;
  455.  
  456.      case TMIPC_DeleteTMObject: rc=InternalDeleteTMObject(handle,
  457.                                                           handle->tmh_Object);
  458.                                 break;
  459.  
  460.      case TMIPC_ChangeTMObject: rc=InternalChangeTMObject(handle,
  461.                                                           handle->tmh_Object,
  462.                                                           handle->tmh_Tags);
  463.                                 break;
  464.     }
  465.  
  466.     /* Reply message */
  467.     handle->tmh_Command=rc;
  468.     DEBUG_PRINTF("Command reply (%1lx)\n",handle->tmh_Command);
  469.     ReplyMsg((struct Message *) handle);
  470.    }
  471.   }
  472.  
  473.   /* Got a configuration file notification event? */
  474.   if (gotsigs & npsig) {
  475.  
  476.    DEBUG_PRINTF("Preferences changed!\n");
  477.  
  478.    /* Free old config */
  479.    InternalFreeTMHandle(PrivateTMHandle);
  480.    FreeConfig();
  481.  
  482.    /* Read new config */
  483.    ReadConfig();
  484.   }
  485.  
  486.   /* Got a Workbench Close/Open event? */
  487.   if (gotsigs & scsig) {
  488.    struct ScreenNotifyMessage *snm;
  489.  
  490.    DEBUG_PRINTF("ScreenNotify event!\n");
  491.  
  492.    /* Retrieve message from port */
  493.    while (snm = (struct ScreenNotifyMessage *) GetMsg(ScreenNotifyPort)) {
  494.  
  495.     /* Which event? */
  496.     switch (snm->snm_Type) {
  497.      case SCREENNOTIFY_TYPE_CLOSESCREEN:
  498.       ScreenCloseEvent(snm->snm_Value);
  499.       break;
  500.  
  501.      case SCREENNOTIFY_TYPE_PUBLICSCREEN:
  502.       ScreenOpenEvent(((struct PubScreenNode *) snm->snm_Value)->psn_Node.ln_Name);
  503.       break;
  504.  
  505.      case SCREENNOTIFY_TYPE_PRIVATESCREEN:
  506.       ScreenCloseEvent(((struct PubScreenNode *) snm->snm_Value)->psn_Screen);
  507.       break;
  508.  
  509.      case SCREENNOTIFY_TYPE_WORKBENCH:
  510.       /* Close or open event? */
  511.       switch (snm->snm_Value) {
  512.        case FALSE: {            /* Close event */
  513.          struct Screen *s;
  514.  
  515.          /* Lock Workbench screen */
  516.          if (s = LockPubScreen(WBName)) {
  517.           /* Close docks */
  518.           ScreenCloseEvent(s);
  519.  
  520.           /* Unlock Workbench screen */
  521.           UnlockPubScreen(NULL, s);
  522.          }
  523.         }
  524.         break;
  525.  
  526.        case TRUE:               /* Open event */
  527.         ScreenOpenEvent(WBName);
  528.         break;
  529.       }
  530.       break;
  531.     }
  532.  
  533.     /* Reply message */
  534.     ReplyMsg((struct Message *) snm);
  535.    }
  536.   }
  537.  }
  538.  
  539.  /* Deactivate broker */
  540.  ActivateCxObj(Broker,FALSE);
  541.  
  542.  /* Free config buffers */
  543.  InternalFreeTMHandle(PrivateTMHandle);
  544.  FreeConfig();
  545.  
  546.  /* Free all resources &  Reset closing flag */
  547.  DEBUG_PUTSTR("Handler signing off...\n")
  548. /* Forbid(); */
  549.  FreeResources();
  550.  Closing=FALSE;
  551. }
  552.